#ifndef __UDSF_CSTDLIKE_C_
#define __UDSF_CSTDLIKE_C_

#include "udf_global.h"
/*
*   notice:
*   UDSF 同UDF编程：不可调用cstd-lib,只可调用"sdk_ifs_udk_cfg.h"、"sys_api.h"中列出的API函数。
*   UDSF文件内函数均需使用static修饰符，且UDF中以#include "UDSF.c"形式引用
*/
#include "udsf_sys_api.c"

static void udsf_memcpy(uint8_t* src,uint8_t* dst,int len) __attribute__((unused));
static void udsf_memset(uint8_t* dst,uint8_t value,int len) __attribute__((unused));
static void udsf_memcpy32(uint32_t* src,uint32_t* dst,int len) __attribute__((unused));
static void udsf_memcpy32_hw(uint32_t*src,uint32_t*dst,int len) __attribute__((unused));
static uint32_t udsf_abs( int value) __attribute__((unused));
static uint16_t udsf_sqrt_16(uint32_t M) __attribute__((unused));

static uint16_t udsf_sqrt_16(uint32_t M)
{
     uint16_t N, i;
     uint32_t tmp, ttp;  // 结果、循环计数
 
     if (M == 0)  // 被开方数，开方结果也为0
         return 0;
 
     N = 0;
     tmp = (M >> 30);  // 获取最高位：B[m-1]
     M <<= 2;
 
     if (tmp > 1)   // 最高位为1
     {
         N ++;      // 结果当前位为1，否则为默认的0
         tmp -= N;
     }
 
     for (i=15; i>0; i--)   // 求剩余的15位
     {
         N <<= 1;     // 左移一位
         tmp <<= 2;
         tmp += (M >> 30);  // 假设
         ttp = N;
         ttp = (ttp<<1)+1;
 
         M <<= 2;
         if (tmp >= ttp)   // 假设成立
         {
             tmp -= ttp;
             N ++;
         }
     }
     return N;
}

static uint16_t udsf_calEucDistance(int16_t x1, uint16_t y1, int16_t x2, uint16_t y2) __attribute__((unused));
static uint16_t udsf_calEucDistance(int16_t x1, uint16_t y1, int16_t x2, uint16_t y2)
{
    uint16_t distance = 0;
    int32_t delta_x2 = (x1 - x2) * (x1 - x2);
    int32_t delta_y2 = (y1 - y2) * (y1 - y2);
    uint32_t delta_r = delta_x2 + delta_y2;
    distance = udsf_sqrt_16(delta_r);
    return distance;
}

static uint16_t udsf_calEucDistance_V(int16_t x1, uint16_t y1, uint8_t v1,int16_t x2, uint16_t y2,uint8_t v2) __attribute__((unused));
static uint16_t udsf_calEucDistance_V(int16_t x1, uint16_t y1, uint8_t v1,int16_t x2, uint16_t y2,uint8_t v2)
{
    uint16_t distance = 0;
    int32_t delta_x2 = (x1 - x2) * (x1 - x2);
    int32_t delta_y2 = (y1 - y2) * (y1 - y2);
    int8_t  delta_v =  (v1 - v2) * (v1 - v2);
    uint32_t delta_r = delta_x2 + delta_y2 + 10*delta_v;
    distance = udsf_sqrt_16(delta_r);
    return distance;
}

static uint32_t udsf_abs(int value){
	if( value >= 0 ){
		return value;
	}else{
		return (0-value);
	}
}

static void udsf_memcpy32_hw(uint32_t*src,uint32_t*dst,int len){ // notice: src or dst addr must in abufx;and src and dst must in diffrent abufx。

	P2_FFT_CONFIG p2_cfg;

	//intraCnt,fix2pfLsfB,max_clr,p2_fft_mode,dma_dsize,rsfBit,sub_mode,mode
	p2_cfg.p2Cfg0 = (len - 1) << 20 | P2_FIX2PF_LSFB_0BIT << 17 | P2_MAX_CLR_EN << 16 | P2_FFT_MODE_DIS << 14 | P2_DMA_DSIZE_32BIT << 12 | P2_RSF_DIV1 << 8 | P2_SUBMODE_0 << 4 |P2_MODE_DMA;
	p2_cfg.p2Cfg1 = 0,
	p2_cfg.p2Cfg2 = 0,
	p2_cfg.p2Cfg3 = 0,
	p2_cfg.p2Cfg4 = (NUM_BYTE32) << 16 | (GET_OFFSET((uint32_t)src)) << 0, // covered by udf03
	p2_cfg.p2Cfg5 = 0,
	p2_cfg.p2Cfg6 = 0,
	p2_cfg.p2Cfg7 = 0,
	p2_cfg.p2Cfg8 = (NUM_BYTE32) << 16 | (GET_OFFSET((uint32_t)dst)) << 0, // covered by udf03

	P2_FFT_HANDLE(&p2_cfg);
}

static int udsf_memcmp(uint8_t* src0,uint8_t* src1,int len) __attribute__((unused));
static char* udsf_strstr(const char* str1,const char* str2) __attribute__((unused));

static char* udsf_strstr(const char* str1,const char* str2)
{
	char *cp = (char *)str1;
	char *s1, *s2;

	if (!*str2)
			return((char *)str1);
	
	while (*cp)
	{
			s1 = cp;
			s2 = (char *)str2;
		
			while (*s2 && !(*s1 - *s2))
					s1++, s2++;
			
			if (!*s2)
					return(cp);
			
			cp++;
	}
	
	return(NULL);
}

static int udsf_memcmp(uint8_t* src0,uint8_t* src1,int len){
	
	int ret = 0;
	
	for( int i = 0;i<len;i++ ){
		if( src0[i] != src1[i] ){
			ret = -1;
			break;
		}
	}
	
	return ret;
}

static void udsf_memcpy(uint8_t* src,uint8_t* dst,int len)
{
	for( int i = 0;i<len;i++ ){
		dst[i] = src[i];
	}
}
//#include "udsf_uart.c"

static void udsf_memcpy32(uint32_t* src,uint32_t* dst,int len)
{
//	LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,(uint32_t*)&src,1,"src ","\n");
//	LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,(uint32_t*)&dst,1,"dst ","\n");
//	LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,(uint32_t*)&len,1,"len ","\n");
	
	for( int i = 0;i<len;i++ ){
		dst[i] = src[i];
	}
}

static void udsf_memset(uint8_t* dst,uint8_t value,int len)
{
	for( int i = 0;i<len;i++ ){
		dst[i] = value;
	}
}

#endif
